﻿#region License
//------------------------------------------------------------
// Copyright (c) Denis Vuyka.  All rights reserved.
// This source code is subject to terms and conditions of the 
// Microsoft Reciprocal License (Ms-RL) License for Carcass. 
// A copy of the license can be found in the License.txt file 
// at the root of this distribution. 
// By using this source code in any fashion, you are agreeing 
// to be bound by the terms of the 
// Microsoft Reciprocal License (Ms-RL) License
// You must not remove this notice from this software.
//------------------------------------------------------------
#endregion

using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using AvalonDock;
using Carcass.Shell;

namespace DemoShell
{
  [Export(Carcass.GlobalContracts.PadManager)]
  public sealed class PadManager : INotifyImportSatisfaction
  {
    [Import(Carcass.GlobalContracts.PadView, AllowRecomposition = true)]
    public ExportCollection<UIElement, IPadViewMetadata> Pads { get; private set; }
    
    [Import(Carcass.GlobalContracts.MainWindow)]
    private Shell _Shell = null;

    [Import]
    private DockingManager _DockingManager = null;
   
    public PadManager()
    {
      Pads = new ExportCollection<UIElement, IPadViewMetadata>();
    }
        
    public void ImportCompleted()
    {
      _Shell.CommandBindings.Add(new CommandBinding(ShellCommands.ActivatePad, OnActivatePadExecuted));
    }

    private void OnActivatePadExecuted(object sender, ExecutedRoutedEventArgs e)
    {
      var pad = e.Parameter as Export<UIElement, IPadViewMetadata>;
      if (pad != null)
        ShowPad(pad);
    }
        
    private void ShowPad(Export<UIElement, IPadViewMetadata> view)
    {
      if (view == null) return;
      var pad = view.GetExportedObject();
      IPadViewMetadata metadata = view.MetadataView;

      DockableContent existing = _DockingManager.DockableContents.FirstOrDefault(i => i.Content == pad);
      if (existing != null)
        _DockingManager.Show(existing, DockableContentState.Docked, DockToAnchorStyle(metadata.Docking));
      else
        _DockingManager.LoadNewDockableContent(pad, metadata.Name, DockToAnchorStyle(metadata.Docking), false);
    }

    /// <summary>
    /// Converts System.Windows.Controls.Dock to AvalonDock.AnchorStyle.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    private static AnchorStyle DockToAnchorStyle(Dock value)
    {
      switch (value)
      {
        case Dock.Bottom: return AnchorStyle.Bottom;
        case Dock.Left: return AnchorStyle.Left;
        case Dock.Right: return AnchorStyle.Right;
        case Dock.Top: return AnchorStyle.Top;
        default: throw new NotSupportedException();
      }
    }    
  }
}
